package com.zgc.view.cell;

import com.fx.spring.util.SpringContextUtil;
import com.jfoenix.controls.JFXTreeCell;
import com.zgc.cache.CuratorClientCache;
import com.zgc.constant.ZkConstant;
import com.zgc.util.CuratorZkUtil;
import com.zgc.view.common.AlertCtrl;
import com.zgc.view.common.DeleteAlertCtrl;
import com.zgc.view.common.PopupCtrl;
import com.zgc.view.controller.CreateZkNodeCtrl;
import com.zgc.view.controller.InformationTabCtrl;
import com.zgc.zkinfo.ZkNodeInfo;
import javafx.scene.control.*;
import org.apache.curator.framework.CuratorFramework;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;

public class ZkNodeTreeViewCell extends JFXTreeCell<ZkNodeInfo> {


    private final InformationTabCtrl informationTabCtrl;
    private final TreeView<ZkNodeInfo> treeView;
    private final AlertCtrl alertCtrl = SpringContextUtil.getBean(AlertCtrl.class);
    private final CreateZkNodeCtrl createZkNodeCtrl = SpringContextUtil.getBean(CreateZkNodeCtrl.class);
    private final DeleteAlertCtrl deleteAlertCtrl = SpringContextUtil.getBean(DeleteAlertCtrl.class);
    private final PopupCtrl popupCtrl = SpringContextUtil.getBean(PopupCtrl.class);

    public ZkNodeTreeViewCell(InformationTabCtrl informationTabCtrl, TreeView<ZkNodeInfo> treeView) {
        this.informationTabCtrl = informationTabCtrl;
        this.treeView = treeView;
    }

    @Override
    protected void updateItem(ZkNodeInfo item, boolean empty) {
        super.updateItem(item, empty);
        if (empty || item == null) {
            setText(null);
            setGraphic(null);
        } else {
            setText(item.getCurrentPath());
            setContextMenu(initContextMenu(item));
        }
    }

    @Override
    public void updateIndex(int i) {
        super.updateIndex(i);
    }

    private ContextMenu initContextMenu(ZkNodeInfo zkNodeInfo) {
        // 节点菜单
        MenuItem createNode = new MenuItem("新建");
        MenuItem refreshNode = new MenuItem("刷新");
        MenuItem deleteNode = new MenuItem("删除");

        MenuItem showNode = new MenuItem("显示节点");
        MenuItem hideNode = new MenuItem("隐藏节点");

        createNode.setOnAction(event -> createZkNodeCtrl.createAndShow(zkNodeInfo));
        refreshNode.setOnAction(event -> informationTabCtrl.refreshZkNode(treeView.getSelectionModel().getSelectedItem()));
        showNode.setOnAction(event -> informationTabCtrl.expandedOrCloseTree(treeView.getSelectionModel().getSelectedItem(), true));
        hideNode.setOnAction(event -> informationTabCtrl.expandedOrCloseTree(treeView.getSelectionModel().getSelectedItem(), false));
        deleteNode.setOnAction(event -> {
            if (ZkConstant.ROOT_NODE.equals(zkNodeInfo.getPath()) || ZkConstant.ZOOKEEPER_NODE.equals(zkNodeInfo.getPath())) {
                alertCtrl.setMessageAndShow(MessageFormat.format("[{0}]节点不能被删除", zkNodeInfo.getPath()));
                return;
            }
            CuratorFramework curatorClient = CuratorClientCache.getCuratorClient(zkNodeInfo.getId());
            String[] messages = getZkChildrenPath(curatorClient, treeView.getSelectionModel().getSelectedItem());
            deleteAlertCtrl.setMessageAndShow("删除节点", "节点删除后将不能恢复,请谨慎操作", messages, event1 -> {
                if (CuratorZkUtil.delete(curatorClient, zkNodeInfo.getPath())) {
                    deleteAlertCtrl.close();
                    popupCtrl.enqueueRoot("节点删除成功", messages);
                } else {
                    popupCtrl.enqueueOne(deleteAlertCtrl.getRoot(), "节点删除失败", messages);
                }
            });
        });
        return new ContextMenu(createNode, refreshNode, deleteNode, new SeparatorMenuItem(), showNode, hideNode);
    }

    public String[] getZkChildrenPath(CuratorFramework curatorClient, TreeItem<ZkNodeInfo> selectedItem) {

        AtomicReference<TreeItem<ZkNodeInfo>> currentSelectedItem = new AtomicReference<>(selectedItem);
        ArrayList<String> messages = new ArrayList<>();
        messages.add(selectedItem.getValue().getPath());
        while (!currentSelectedItem.get().isLeaf()) {
            currentSelectedItem.get().getChildren().forEach(selectedItem1 -> {
                currentSelectedItem.set(selectedItem1);
                messages.add(selectedItem1.getValue().getPath());
            });
        }
        messages.forEach(path -> {
            if (!CuratorZkUtil.exit(curatorClient, path)) {
                messages.add(path + "(节点不存在)");
            }
        });
        return messages.toArray(String[]::new);
    }
}
